package com.example.demo.app.controller;

import javax.annotation.Resource;

import com.example.demo.config.Persistence.PersistConfig;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.app.entity.OrderEntity;
import com.example.demo.config.builder.FormStateMachineBuilder;
import com.example.demo.config.builder.OrderStateMachineBuilder;
import com.example.demo.config.enum_.FormEvents;
import com.example.demo.config.enum_.FormStates;
import com.example.demo.config.enum_.OrderEvents;
import com.example.demo.config.enum_.OrderStates;

import lombok.extern.slf4j.Slf4j;

@RestController
@RequestMapping("/")
@Slf4j
public class StateMachineController {
	@Autowired
	private OrderStateMachineBuilder orderStateMachineBuilder;
	@Autowired
	private FormStateMachineBuilder formStateMachineBuilder;
	//@Resource(name = "orderRedisPersister") // 持久化
	private StateMachinePersister<OrderStates, OrderEvents, String> orderRedispersister;

	@Resource(name= PersistConfig.orderPersister)
	private StateMachinePersister<OrderStates, OrderEvents, OrderEntity> persister;
	@RequestMapping("/0")
	public void testSingleOrderState(@RequestParam(name = "id") String id) throws Exception {

		StateMachine<OrderStates, OrderEvents> stateMachine = orderStateMachineBuilder.build();
		System.out.println("=======>" + stateMachine.getId());
		// 创建流程
		stateMachine.start();

		// 触发PAY事件
		stateMachine.sendEvent(OrderEvents.PAY);

		// 触发RECEIVE事件
		// stateMachine.sendEvent(OrderEvents.RECEIVE);

		OrderEntity orderEntity = new OrderEntity(id, "订单" + id, "RECEIVE");
		Message<OrderEvents> message = MessageBuilder.withPayload(OrderEvents.RECEIVE).setHeader("order", orderEntity)
				.setHeader("order1", orderEntity).setHeader("order2", orderEntity).build();
		stateMachine.sendEvent(message);
		// 获取最终状态
		System.out.println("最终状态：" + stateMachine.getState().getId());
	}

	@RequestMapping("/1")
	public void testFormState() throws Exception {

		StateMachine<FormStates, FormEvents> stateMachine = formStateMachineBuilder.build();
		System.out.println("=======>" + stateMachine.getId());

		// 创建流程
		stateMachine.start();

		stateMachine.sendEvent(FormEvents.WRITE);

		stateMachine.sendEvent(FormEvents.CONFIRM);

		stateMachine.sendEvent(FormEvents.CONFIRM);

		stateMachine.sendEvent(FormEvents.SUBMIT);

		// 获取最终状态
		System.out.println("最终状态：" + stateMachine.getState().getId());
	}


	// 保存状态机
	@RequestMapping("/testRedisPersister")
	public void testRedisPersister(String id) throws Exception {
		StateMachine<OrderStates, OrderEvents> stateMachine = orderStateMachineBuilder.build();
		stateMachine.start();
		// 发送PAY事件
		stateMachine.sendEvent(OrderEvents.PAY);
		OrderEntity order = new OrderEntity(id, null, null);
		// 持久化stateMachine
		orderRedispersister.persist(stateMachine, order.getId());
	}

	// 取出状态机
	@RequestMapping("/testRedisPersisterRestore")
	public void testRedisRestore(String id) throws Exception {
		StateMachine<OrderStates, OrderEvents> stateMachine = orderStateMachineBuilder.build();
		orderRedispersister.restore(stateMachine, id);
		System.out.println("恢复状态机后的状态为：" + stateMachine.getState().getId());
	}

	 @RequestMapping("/testOrderRestore")
		public void testOrderRestore(String id,String status) throws Exception {
			StateMachine<OrderStates, OrderEvents> stateMachine = orderStateMachineBuilder.build();
			//订单
			OrderEntity order = new OrderEntity(id, id, status);
			//恢复
			persister.restore(stateMachine, order);
			//查看恢复后状态机的状态
			System.out.println("恢复后的状态：" + stateMachine.getState().getId());
		}
	
}
